#include "../Base.h"


VOID EnumNode(_RTL_BALANCED_NODE* node) {
	
	if (!node) return;

	LOG("Node Address = %llx", node);
	if(node->Left)
	EnumNode(node->Left);
	if(node->Right)
	EnumNode(node->Right);


}


NTSTATUS EnumMmVadOfProcess(PEPROCESS process)
{
	PMMVAD  root = (PMMVAD)((_RTL_AVL_TREE*)((PUCHAR)process + 0x658))->Root;
	if (root) {
		EnumNode(((_RTL_BALANCED_NODE*)root));
	}
	
	return STATUS_SUCCESS;
}

PMMVAD FindVadNodeByVirtualAddress(PEPROCESS process,ULONG_PTR Va) {
	ULONG_PTR vaT = Va>>12;

	PMMVAD  root = (PMMVAD)((_RTL_AVL_TREE*)((PUCHAR)process + 0x658))->Root;
	if (root) {
		while (1) {
			if (vaT > ((ULONG_PTR)root->Core.EndingVpn | (ULONG_PTR)root->Core.EndingVpnHigh << 32)) {
				root = (_MMVAD*)root->Core.ExtraCreateInfo;//right
			}
			else {
				if (vaT >= ((ULONG_PTR)(root->Core.StartingVpn) | (ULONG_PTR)(root->Core.StartingVpnHigh << 32))) {
					return root;
				}
				root = (_MMVAD*)root->Core.NextVad;//left
			}
			if (!root) {
				return 0;
			}
		}
	}
	return 0;
}

NTSTATUS CombineMmvad(PEPROCESS process,ULONG_PTR va)
{
	PMMVAD vad = FindVadNodeByVirtualAddress(process, va);
	PMMVAD bigVad = (PMMVAD)vad->Core.ExtraCreateInfo;
	vad->Core.EndingVpn = bigVad->Core.EndingVpn;
	vad->Core.EndingVpnHigh = bigVad->Core.EndingVpnHigh>>32;
	bigVad->Core.StartingVpn = vad->Core.StartingVpn;
	bigVad->Core.StartingVpnHigh = vad->Core.StartingVpnHigh>>32;
	return STATUS_SUCCESS;
}
